package models

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"encoding/hex"
	"github.com/google/uuid"
	"strings"
	"time"
)

type Password struct {
	Uuid     string
	Account  string
	Password string
	Remark   string
	Datetime string
}

/*创建密码*/
func (password *Password) Create(remark string) (*Password, error) {
	password.Uuid = strings.ReplaceAll(uuid.NewString(), "-", "")
	password.Datetime = time.Now().Format("2006-01-02 15:04:05")

	key, _ := hex.DecodeString(password.Uuid)
	plaintext := []byte(password.Password)
	c := make([]byte, aes.BlockSize)
	iv := c[:aes.BlockSize]

	//加密
	cipherText, err := AesEncrypt(plaintext, key, iv)
	if err != nil {
		panic(err)
	}

	password.Password = base64.StdEncoding.EncodeToString(cipherText)
	password.Remark = remark
	return password, nil
}

func PKCS7Padding(cipherText []byte, blockSize int) []byte {
	padding := blockSize - len(cipherText)%blockSize
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(cipherText, padText...)
}

func PKCS7UnPadding(origData []byte) []byte {
	length := len(origData)
	unPadding := int(origData[length-1])
	return origData[:(length - unPadding)]
}

//AesEncrypt 加密函数
func AesEncrypt(plaintext []byte, key, iv []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	plaintext = PKCS7Padding(plaintext, blockSize)
	blockMode := cipher.NewCBCEncrypter(block, iv)
	crypted := make([]byte, len(plaintext))
	blockMode.CryptBlocks(crypted, plaintext)
	return crypted, nil
}

// AesDecrypt 解密函数
func AesDecrypt(ciphertext []byte, key, iv []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	blockMode := cipher.NewCBCDecrypter(block, iv[:blockSize])
	origData := make([]byte, len(ciphertext))
	blockMode.CryptBlocks(origData, ciphertext)
	origData = PKCS7UnPadding(origData)
	return origData, nil
}
